package ui;

import infrastructure.exceptions.operations.OperationException;
import inftrastructure.exceptions.ClientRuntimeException;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import server.IAdminInterface;
import dal.User;

public class AddUserDialog extends JDialog implements ActionListener{
	
	// Data Members Definition
	final String[] OPTIONS = {"NO", "YES"}; 
	private String userName = null;
	private String userPassword = null ;
	private boolean isAdmin = false;
	private boolean userExists = false;
	private ManageUsersFrame parentFrame = null;
	private char[] password = null;
	private Iterator<User> usersIter = null;
	private IAdminInterface session = null;
	
	// Components Definition
	private Container mainCotainer = null;
	private JPanel dialogPanel = new JPanel(new GridBagLayout());
	private JPanel buttonsPanel = new JPanel(new FlowLayout());
	private JComboBox isAdminComboBox = null;
	private JTextField userNameField = new JTextField(15);
	private JPasswordField passwordField = new JPasswordField(10);
	private JLabel userNameLabel = new JLabel ("UserName:");
	private JLabel passwordLabel = new JLabel ("User's Password:");
	private JLabel isAdminLabel = new JLabel ("Is Administrator:");
	private JButton okButton = new JButton ("OK");
	private JButton cancelButton = new JButton ("Cancel");
	
	private JLabel[] labels = {userNameLabel, passwordLabel, isAdminLabel};
	private JTextField[] textFields = {userNameField, passwordField};
	
	// Constructor Definition
	public AddUserDialog (ManageUsersFrame parentframe, String title)
	{
		// Set the title
		super(parentframe,title);
				
		// Set reference to the parent frame
		parentFrame = parentframe;
		
		// Initialize IsAdmin CmboBox and set NO as default option
		isAdminComboBox = new JComboBox(OPTIONS);
		isAdminComboBox.setFont(new Font("DialogInput", Font.PLAIN, 12));
		isAdminComboBox.setEditable(false);
		isAdminComboBox.setSelectedIndex(0);
		
		// Format fields and labels
		userNameField.setFont(new Font("DialogInput", Font.PLAIN, 12));
		userNameLabel.setLabelFor(userNameField);
		passwordLabel.setLabelFor(passwordField);
		isAdminLabel.setLabelFor(isAdminComboBox);

		// Add components to container
		addtextRows(labels, textFields, 
				dialogPanel);
		buttonsPanel.add(okButton);
		buttonsPanel.add(cancelButton);
		getContentPane().add(dialogPanel, BorderLayout.CENTER);
		getContentPane().add(buttonsPanel, BorderLayout.SOUTH);
		
		// Set buttons' ActionListners
		okButton.addActionListener(this);
		cancelButton.addActionListener(this);
		
		// Initialize the dialog and display the Windows
		setModal(true);
		setSize(350,350);
		setResizable(false);
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		pack();
		setLocationRelativeTo(null);
		setVisible(true);
	}
	
	public void actionPerformed(ActionEvent e) {
		
		if (e.getSource() == okButton)
		{
			// Check if the user entered an Username (note that the password can be empty)
			if (userNameField.getText() == null || userNameField.getText().equals(""))
			{
				JOptionPane.showMessageDialog(null, "You must enter UserName",
						"Warning", JOptionPane.WARNING_MESSAGE);
			}
			else
			{
				password = passwordField.getPassword();	
				if (password == null )
				{
					// Set empty password
					userPassword = new String("");
				}
				else
				{
					userPassword = new String(password);
				}
				
				userName = userNameField.getText();
				if (isAdminComboBox.getSelectedIndex() == 1)
				{
					// New User is an Administrator
					isAdmin = true;
					
				}
				
				// Get the IAdminInterface from current session
				session = (IAdminInterface)parentFrame.callingFrame.currClient.session;
				
				try
				{
					userExists = false;
					// Check if we already got the user iterator
					if (usersIter == null)
					{
						usersIter = session.getAllUsers();
					}
					
					// Check if the user is already defined in the system
					while (usersIter.hasNext())
					{				
						if (usersIter.next().equals(userName))
						{
							JOptionPane.showMessageDialog(null, "User " + userName + " already exists in the system!",
									"User Already Exists", JOptionPane.ERROR_MESSAGE);
							userExists = true;
							userNameField.setText(null);
							return;
						}
					}
				}
				catch (Exception ex)
				{
					throw new ClientRuntimeException(ex.getMessage(), ex);
				}
				if (!userExists)
				{
					try
					{
						// If it's a new user then insert him into DB
						session.addUser(userName, userPassword, isAdmin);
					}
					catch (OperationException ex)
					{
						JOptionPane.showMessageDialog(null, "Adding user " + userName
								+ " failed on the server",
								"Error", JOptionPane.ERROR_MESSAGE);
						return;
					}
					catch (Exception ex)
					{
						throw new ClientRuntimeException(ex.getMessage(), ex);
					}
					dispose();
				}
			}
		}
		else if (e.getSource() == cancelButton)
		{
			dispose();	
		}
	}

	
	private void addtextRows(JLabel[] labels, JTextField[] textfields, 
			Container container)
	{
		/** This methods add components to grid using GridBagConstraints.
		 *  The GridBagLayout is compound from 4 rows and 3 columns */
		
		int index;
		int numofFields = textfields.length;
		Insets insets = new Insets(4,2,2,2);
		GridBagConstraints labelsConstrains = new GridBagConstraints();
		GridBagConstraints textfieldsConstrains = new GridBagConstraints();
		
		// Set constraints for labels
		labelsConstrains.gridx = 0; // labels at the left column
		labelsConstrains.gridy = 0;
		labelsConstrains.anchor = GridBagConstraints.FIRST_LINE_START; // align label to the uperleft
		labelsConstrains.gridwidth = 1; // each label occupies 1 cell
		labelsConstrains.fill = GridBagConstraints.NONE;
		labelsConstrains.weightx = 0.0;
		labelsConstrains.weighty = 0.0;
		labelsConstrains.insets = insets;
		
		// Set constraints for text fields and ComboBox
		textfieldsConstrains.gridx = 1; // text fields at the second column 
		textfieldsConstrains.gridy = 0;
		textfieldsConstrains.anchor = GridBagConstraints.FIRST_LINE_START; // align text fields to the left
		textfieldsConstrains.gridwidth = 2; // each text field occupies 2 cells
		textfieldsConstrains.weightx = 1.0;
		textfieldsConstrains.weighty = 0.0;
		textfieldsConstrains.insets = insets;
		textfieldsConstrains.fill = GridBagConstraints.HORIZONTAL;
		
		for (index = 0; index < numofFields; index++)
		{
			container.add(labels[index], labelsConstrains);
			container.add(textfields[index], textfieldsConstrains);
			labelsConstrains.gridy++;
			textfieldsConstrains.gridy++;
		}
		
		// Put delivered user and its label in layout
		container.add(labels[index], labelsConstrains);
		container.add(isAdminComboBox, textfieldsConstrains);
	}

}
